package cn.piggy.gateway.core.proxy;

import cn.piggy.gateway.core.executor.result.SessionResult;
import cn.piggy.gateway.core.http.HttpCommandType;
import cn.piggy.gateway.core.session.GatewaySession;
import com.netflix.hystrix.*;
import java.util.Map;


public class MethodIntercept extends HystrixCommand<Object> {
    private final GatewaySession session;
    private final Map<String, Object> params;

    public MethodIntercept(GatewaySession session, Map<String, Object> params) {
        super(Setter
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey(session.getHttpStatement().getApplication()))
                .andCommandKey(HystrixCommandKey.Factory.asKey("key"+session.getHttpStatement().getUri().replace("/",":")))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(session.getHttpStatement().getApplication()))
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(100))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withCircuitBreakerEnabled(true)
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                        .withExecutionTimeoutInMilliseconds(3000)
                        .withCircuitBreakerRequestVolumeThreshold(10)
                        .withCircuitBreakerErrorThresholdPercentage(80))
        );
        this.session = session;
        this.params = params;
    }

    @Override
    protected Object getFallback() {
        return SessionResult.buildError("服务降级");
    }

    @Override
    protected Object run() {
        Object result;
        HttpCommandType httpCommandType = session.getHttpStatement().getHttpCommandType();
        switch (httpCommandType) {
            case GET:
                result = session.get(params);
                break;
            case POST:
                result = session.post(params);
                break;
            case PUT:
                result = session.put(params);
                break;
            case DELETE:
                result = session.delete(params);
                break;
            default:
                throw new RuntimeException("Unknown execution method for: " + httpCommandType);
        }
        return result;
    }

}
